let fs = require('fs');
//解析这个请求
module.exports=(dwg,data,head,end)=>{
  //file有种可能，完整数据，上半部分数据，部分数据，下半部分数据
  //判断有没有头部或者尾部，有头不一定有尾，有尾一定会监测出头
  if(data.includes(head)){
      //判断这一段流是否是尾部
      let a = data.indexOf(end);
      //判断有没有尾部数据,或者尾部是正常的分界线
      if( a !== -1 || data.endsWith(head)){
          //判断分界线是否是开头
          if(!data.startsWith(head)){
            //把最前面的数据拿到手
            let sj = data.substring(0,data.indexOf(head));
            if(dwg["temporary"].filename===undefined){
              //这不是一个文件
              dwg["temporary"].data+=sj;
              dwg.parameter[dwg["temporary"].name]=dwg["temporary"].data;
            }else{
              //这是一个文件
              //把前面多余的数据保存完整
              let path = wrfile(dwg["temporary"].filename,sj,true);
              dwg.parameter[dwg["temporary"].name] = maxfile(dwg["temporary"],path);
              data = data.substring(data.indexOf(head)+head.length);
            }
            dwg["temporary"]={};
            //接下来就是有头有尾的正常数了
          }
          //有头有尾，是一个完整的请求，进行解析， 一次流就可以加载完的数据，就算是文件，也不用缓存在本地
          let arr = data.match(/0d0a((?!2d2d2d2d2d2d).)*/g);
          arr && arr.forEach(e=>{
          if(!e.includes('436f6e74656e742d446973706f736974696f6e')){return}
            let obj = jxname(e);
            e = e.match(/0d0a0d0a.*/);
            if(!e){console.log('post解析不该出现的错误却出现了'); return;}
            e = e[0].substring(8,e[0].length-4);
            if(obj.filename){
              //是文件
              obj.data = e;
              dwg.parameter[obj.name] = minfile(obj);
            }else{
              dwg.parameter[obj.name]=toVariable(e);
            }
          })
      }else{
          //没有尾部分界线，说明这是一个半成品，保存到temporary里面
          //把尾部数据提取出来
          let wei = data.match(/0d0a((?!2d2d2d2d2d2d).)*$/)[0];
          if(wei.includes('436f6e74656e742d446973706f736974696f6e')){
            //有效数据，解析属性
            let obj = jxname(wei);
            wei = wei.match(/0d0a0d0a.*/);
            if(!wei){console.log('post解析不该出现的错误却出现了'); return;}
            //,wei[0].length-4
            wei = wei[0].substring(8);
          //判读是否为文件
            if(obj.filename){
              //是文件，保存为缓存
              obj.path = wrfile(obj.filename,wei);
            }else{
              //不是文件
              obj.data = wei;
            }
            dwg.temporary = obj;
          }
          //清除尾部数据
          data = data.replace(/0d0a((?!2d2d2d2d2d2d).)*$/,"")
          //判断头部数据起始位置是否为0
          if(!data.startsWith(head)){
            //起始位置不为0，把前部分数据合并完整
            //把最前面的数据拿到手
            let sj = data.substring(0,data.indexOf(head));
            if(dwg["temporary"].filename===undefined){
              //这不是一个文件
              dwg["temporary"].data+=sj;
              dwg.parameter[dwg["temporary"].name]=dwg["temporary"].data;
              // req[dwg["temporary"].name]=dwg["temporary"].data;
            }else{
              //这是一个文件
              //把前面多余的数据保存完整
              let path = wrfile(dwg["temporary"].filename,sj,true);
              dwg.parameter[dwg["temporary"].name] = maxfile(dwg["temporary"],path);
              // req[dwg["temporary"].name]= dwg.parameter[dwg["temporary"].name];
            }
            data = data.substring(data.indexOf(head)+head.length);
            dwg["temporary"]={};
          }
          //执行接下来的数据
          let arr = data.match(/0d0a((?!2d2d2d2d2d2d).)*/g);
          arr && arr.forEach(e=>{
            if(!e.includes('436f6e74656e742d446973706f736974696f6e')){return}
            let obj = jxname(e);
            e = e.match(/0d0a0d0a.*/);
            if(!e){console.log('post解析不该出现的错误却出现了'); return;}
            e = e[0].substring(8,e[0].length-4);
            if(obj.filename){
              //是文件
              obj.data = e;
              dwg.parameter[obj.name] = minfile(obj);
            }else{
              dwg.parameter[obj.name]=toVariable(e);
            }
          })
      }
  }else{
      //这里都是无头无尾的数据
      //保存到缓存区，判断是否是文件
      if(dwg["temporary"].filename){
        //是文件
        dwg["temporary"].path = wrfile(dwg["temporary"].filename,data,true);
      }else{
        //不是文件，一般不可能有这么大的参数
        dwg["temporary"].data += data;
      }
  }
  
  //解析出参数，名称以及文件名称,如果有文件名称的话
  function jxname(str){
    //如果数据中不包含Content-Disposition直接返回
    if(!str.includes('436f6e74656e742d446973706f736974696f6e')){return false}
    str = str.substring(0,str.indexOf('0d0a0d0a'));
    str = Buffer.from(str,"hex").toString("utf-8").replace(/[\r" ]/g,"");
    // obj['size']=req.headers['content-length']?(req.headers['content-length']):"未知";

    let obj = str.match(/([^\n;]*=*[^\n])/g).reduce((par, e) => {
      e = e.replace(/[\n\r;]/g, "");
      let arr = e.split(/: |=|:/);
      if (arr.length <= 1 || arr[0] === "") {
        return par
      }
      par[arr[0]] = arr[1]
      return par;
    }, {});
    return obj;
  }

  //把文件保存到临时目录
  function wrfile(name,data,continuing){
    // console.log("写入文件");
    //尾部是\r\n就去除
    if(data.endsWith("0d0a")){
      data = data.substring(0,data.length-4);
    }
    //变为二进制数据
    data = Buffer.from(data,"hex");
    //没有临时文件夹就创建
    if(!fs.existsSync(process.cwd()+'/.temporary')){fs.mkdirSync(process.cwd()+'/.temporary')}

    //如果continuing等于未定义，那就代表这是新文件，直接创建
    if(continuing === undefined){
      fs.writeFileSync(process.cwd()+"/.temporary/"+name,data,"binary");      
    }else{
      //否则就在原有文件的情况下把数据追加进去
      fs.appendFileSync(process.cwd()+"/.temporary/"+name,data,"binary");
      // console.log("追加成功","./.temporary/"+name,data);
    }
    return process.cwd()+"/.temporary/"+name;
  }

  //把普通二进制参数转换成变量
  function toVariable(buf){
    let str = Buffer.from(buf,"hex").toString("utf-8");
    try{
      return JSON.parse(str);
    }catch(err){ //报错说明是一个普通字符串
      return str;
    }
  }


  //生成大文件对象
  function maxfile(obj,path){
    obj.read=()=>fs.readFileSync(path);
    obj.write=(pa)=>{
      fs.createReadStream(path).pipe(fs.createWriteStream(pa))
      fs.unlinkSync(path);
    }
    try{
      obj.size = fs.statSync(obj.path).size;
    }catch(err){
      console.log(err);
    }
    return obj;
  }

  function minfile(obj){
    obj.read=()=>Buffer.from(obj.data,'hex').toString('utf-8');
    obj.write=(pa)=>{
      fs.writeFileSync(pa,Buffer.from(obj.data,'hex'));
    }
    obj.size = Buffer.byteLength(obj.data,'hex');
    return obj;
  }
}